﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Diagnostics;

/*
打包成单个exe
dotnet publish -c Release -r win-x64 --self-contained true /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true
 */
namespace NodeEditor
{
    public partial class MainWindow : Window {

        NodeGraphContext context;
        NodeGraph nodeGraph;

        List<VarData> globalVarList;

        public MainWindow() {
            Trace.Listeners.Add(new TextWriterTraceListener("log.txt"));
            Trace.AutoFlush = true;

            Trace.WriteLine("MainWindow constructor started.");
            InitializeComponent();
            Trace.WriteLine("InitializeComponent completed.");

            context = new NodeGraphContext();
            nodeGraph = new NodeGraph(context, this);
            globalVarList = new List<VarData>();

            container.Children.Add(nodeGraph);

            // 订阅 Grid 的 LayoutUpdated 事件
            inspectorGrid.LayoutUpdated += inspectorSplite_Updated;

            // 订阅窗口关闭事件
            this.Closed += MainWindow_Closed;

            // 订阅键盘按键事件
            this.KeyDown += MainWindow_KeyDown;
        }

        private void MainWindow_Closed(object sender, EventArgs e) {
            // 移除 TraceListener 并关闭日志文件
            foreach (var listener in Trace.Listeners.OfType<TextWriterTraceListener>()) {
                listener.Flush();
                listener.Close();
            }
            Trace.Listeners.Clear();
        }

        private void MainWindow_KeyDown(object sender, KeyEventArgs e) {
            if (Keyboard.IsKeyDown(Key.LeftCtrl) && e.Key == Key.S) {
                nodeGraph.SaveNodeTreeToJsonByCtrlS(globalVarList);
            }
        }

        private void SaveNodeTreeClick(object sender, RoutedEventArgs e) {
            try {
                nodeGraph.OpenSaveJsonDialog(globalVarList);
            } catch (Exception ex) {
                MessageBox.Show("保存文件时发生错误: " + ex.Message + " " + ex.StackTrace);
                Trace.WriteLine(ex.StackTrace);
            }
        }

        private void LoadNodeTreeClick(object sender, RoutedEventArgs e) {
            globalVarList.Clear();
            scrollContent.Children.Clear();
            globalScrollContent.Children.Clear();
            nodeGraph.OpenLoadJsonDialog();
        }

        public void ChangeNodeEnabled(Node node) {
            bool enabled = node != null;
            nodeName.IsEnabled = enabled;
            nodeDescText.IsEnabled = enabled;
            newVarName.IsEnabled = enabled;

            if (enabled) {
                nodeName.Text = node.title;
                nodeDescText.Text = node.desc;

                SetNodeVarUI(node);
            } else {
                nodeName.Text = "";
                nodeDescText.Text = "";
                scrollContent.Children.Clear();
            }
        }

        private void AddGlobalButton_Click(object sender, RoutedEventArgs e) {
            // 获取输入的变量名称
            string varName = globalVarName.Text;
            string varType = (globalVarType.SelectedItem as ComboBoxItem)?.Content.ToString();
            // 检查输入是否为空
            if (string.IsNullOrWhiteSpace(varName) || string.IsNullOrWhiteSpace(varType)) {
                MessageBox.Show("Please enter a valid name and select a type.", "Error", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            AddGlobalVar(varType, varName);
        }

        public void AddGlobalVar(string varType, string varName, object value = null) {
            // 检查输入是否为空
            if (string.IsNullOrWhiteSpace(varName) || string.IsNullOrWhiteSpace(varType)) {
                return;
            }

            VarData varData;
            if (!Extensions.AddVar(globalVarList, varType, varName, out varData)) {
                MessageBox.Show("Two variable names cannot exist.", "Error", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (value != null) {
                varData.value = value;
            }

            AddNodeVarUI(null, varData);

            // 清空输入框
            globalVarName.Text = string.Empty;
            globalVarType.SelectedIndex = -1;
        }

        private void AddNodeButton_Click(object sender, RoutedEventArgs e) {
            if (nodeGraph.selectNode == null) {
                MessageBox.Show("Please select a node.", "Error", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            // 获取输入的变量名称
            string varName = newVarName.Text;
            string varType = (newVarType.SelectedItem as ComboBoxItem)?.Content.ToString();

            // 检查输入是否为空
            if (string.IsNullOrWhiteSpace(varName) || string.IsNullOrWhiteSpace(varType))
            {
                MessageBox.Show("Please enter a valid name and select a type.", "Error", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            VarData varData;
            var currentNode = nodeGraph.selectNode; // 捕获当前节点
            if (!currentNode.AddVar(varType, varName, out varData)) {
                MessageBox.Show("Two variable names cannot exist.", "Error", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            AddNodeVarUI(currentNode, varData);

            // 清空输入框
            newVarName.Text = string.Empty;
            newVarType.SelectedIndex = -1;
        }

        private void AddNodeVarUI(Node currentNode, VarData varData) {
            string keyName = varData.key;

            Button delValueUI;
            Grid itemGrid;

            if (varData.type == "Bool") {
                BoolProperty item = new BoolProperty { keyName = keyName, keyType = varData.type };
                item.valueChanged += varData.ChangeValue; // 更新值
                item.valueUI.IsChecked = Convert.ToBoolean(varData.value);
                delValueUI = item.delValueUI;

                itemGrid = (Grid)item;
            } else {
                TextProperty item = new TextProperty { keyName = keyName, keyType = varData.type };
                item.valueChanged += varData.ChangeValue; // 更新值
                item.valueUI.Text = varData.value?.ToString();
                delValueUI = item.delValueUI;

                itemGrid = (Grid)item;
            }

            delValueUI.Click += (s, e) => {
                if (currentNode != null) {
                    currentNode.DelVar(keyName);
                } else {
                    Extensions.DelVar(globalVarList, keyName);
                }
                SetNodeVarUI(currentNode);
            };

            if (currentNode != null) {
                scrollContent.Children.Add(itemGrid);
            } else {
                globalScrollContent.Children.Add(itemGrid);
            }
        }

        private void SetNodeVarUI(Node node) {
            List<VarData> list = null;
            if (node != null) {
                scrollContent.Children.Clear();
                list = node.GetAllVar();
            } else {
                globalScrollContent.Children.Clear();
                list = globalVarList;
            }

            foreach (var v in list) {
                AddNodeVarUI(node, v);
            }
        }

        // 调整参数列表滚动条区域可见度高度
        private void AdjustVarScrollViewerHeight() {
            // 获取分割线到底部的高度
            double height = GetGridSplitterToBottomHeight() - 72;
            scrollViewer.Height = height;
        }

        private void inspectorSplite_Updated(object sender, EventArgs e) {
            AdjustVarScrollViewerHeight();
        }

        private double GetGridSplitterToBottomHeight() {
            // 获取 Grid 的总高度
            double totalHeight = inspectorGrid.ActualHeight;

            // 获取分割线所在的行索引
            int splitterRowIndex = 1; // 分割线在 Row 1

            // 累加分割线以上行的高度
            double splitterPosition = 0;
            for (int i = 0; i <= splitterRowIndex; i++) {
                splitterPosition += inspectorGrid.RowDefinitions[i].ActualHeight;
            }

            // 计算分割线到底部的高度
            return totalHeight - splitterPosition;
        }

        private void NodeName_TextChanged(object sender, EventArgs e) {
            if (nodeGraph.selectNode != null) {
                nodeGraph.selectNode.title = nodeName.Text;
            }
        }

        private void NodeDesc_TextChanged(object sender, EventArgs e) {
            if (nodeGraph.selectNode != null) {
                nodeGraph.selectNode.desc = nodeDescText.Text;
            }
        }
    }
}